
local CommonOHOH = _G.CommonOHOH;
local M = CommonOHOH.class.new(script, CommonOHOH.files.BaseComponent());
local animation_cfg = CommonOHOH.config.Animation
local AnimationFolder=Instance.new("Folder",workspace)
AnimationFolder.Name="AnimationFolder"

function M.new(self,...)
	return M(self,...);
end;

function M.ctor(self, parent)
	M.super.ctor(self, parent);
	self.Animations={}
	self.AnimationTrack={}
	self.AnimationTrackLenght={}
	self.AnimationTrackPlayedLastTime={}
	self.LoadingAnimationData={}
end;

function M.dtor(self)

	for k,v in pairs(self.Animations) do
		v:Destroy()
	end
	for k,v in pairs(self.AnimationTrack) do
		v=nil
	end

	self.Animations={}
	self.AnimationTrack={}
	self.AnimationTrackLenght={}
	self.AnimationTrackPlayedLastTime={}
	self.CurrentTrack=nil
	self.ReadToPlayAnmationData=nil
	M.super.dtor(self);
end;


function M.GetAnimator(self)
	return  self.parent:GetHumanoid():WaitForChild("Animator")
end



function M.LoadAnimationSys(self,an)
	return   self.parent:GetHumanoid():LoadAnimation(an)
end


function M.PreLoadAnimationByRid(self,ridList,callBack,animationPriority,loopData)
	local objList={}
	for key,rid in pairs(ridList) do
		local animation= Instance.new("Animation")
		animation.AnimationId=rid
		animation.Name=key
		table.insert(objList,animation)
	end
	self:PreLoadAnimationObject(objList,callBack,animationPriority,loopData)
end
--外部传入动画对象
--参数解释
--AnimationList:动画对象
-- callBack:初始化完成后回调
-- animationPriority:动画属性
-- loopData:包含循环的动画ID,eg:{"idle_1","idle_2"}

function M.PreLoadAnimationObject(self,AnimationList,callBack,animationPriority,loopData)
	self.IsLoading=true
	self:AddProcess(function()
		local Animator =self:GetAnimator()
		while not Animator do
			self:Wait()
			Animator =self:GetAnimator()
		end

		for _,animation in pairs(AnimationList) do
			animation.Parent=Animator

			local priority=nil
			if animationPriority then
				priority=animationPriority[animation.name]
			end
			local isLoop=nil
			if loopData then
				isLoop=loopData[animation.name]
			end
			local track=self:LoadAnimation(animation,animation.name,priority)
			if isLoop then
				track.Looped=true
			end
		end
		self:PlayStackAnimation()
		if callBack then
			callBack()
		end
	end)

end

--加载模型中包含的动画
--参数解释
-- callBack:初始化完成后回调
-- animationPriority:动画属性
-- loopData:包含循环的动画ID,eg:{"idle_1","idle_2"}
function M.PreLoadHadAnimation(self,callBack,animationPriority,loopData)
	self.IsLoading=true
	self:AddProcess(function()
		local Animator =self:GetAnimator()
		while not Animator do
			self:Wait()
			Animator =self:GetAnimator()
		end

		for _,animation in pairs(Animator:GetDescendants()) do

			local priority=nil
			if animationPriority then
				priority=animationPriority[animation.name]
			end
			local isLoop=nil
			if loopData then
				isLoop=loopData[animation.name]
			end
			local track=self:LoadAnimation(animation,animation.name,priority)
			if isLoop then
				track.Looped=true
			end
		end
		self:PlayStackAnimation()
		if callBack then
			callBack()
		end
	end)
end


--加载配置表中的动画
--参数解释
-- AnimationIdList:配置Id列表：{"idle","Attack"}
-- callBack:初始化完成后回调
function M.PreLoadAnimation(self,AnimationIdList,callBack,animationPriority)
	
	-- for k,v in pairs(AnimationIdList) do
	-- 	print("PreLoadAnimation-->",self,k,v)
	-- end
	self.IsLoading=true
	self:AddProcess(function()

		local Animator self:GetAnimator()
		while not Animator do
			self:Wait()
			Animator = self:GetAnimator()
		end

		for _,id in pairs(AnimationIdList) do
			local v=animation_cfg[id]
			assert(v,"animation==null")

			local animation= Instance.new("Animation")
			animation.AnimationId=v.rid
			local priority=nil
			if animationPriority then
				priority=animationPriority[v.name]
			end
			

			local track= self:LoadAnimation(animation,v.name,priority)
			if v.isLoop==1 then
				track.Looped=true
			end
		end

		self:PlayStackAnimation()


		if callBack then
			callBack()
		end

	end)

end

-- 加载一个动画对象
function M.LoadAnimation(self,animation,id,priority)

	if self.Animations[id] then
		return self.AnimationTrack[id]
	end

	local Animator =self:GetAnimator()
	animation.Parent=Animator
	self.Animations[id]=animation
	local animationTrack = self:LoadAnimationSys(animation)
		
	self.AnimationTrack[id]=animationTrack

	if priority then
		animationTrack.Priority=priority
	end

	if not self.AnimationTrackLenght[id] and animationTrack.Length>0 then
		self.AnimationTrackLenght[id]=animationTrack.Length
	end

	return animationTrack
end

--播放堆栈动画（当动画正在初始化中时，业务方提前调用播放后，加载完成，会自动播放）
function M.PlayStackAnimation(self)
	self.IsLoading=nil
	if self.ReadToPlayAnmationData then
		self:PlayAnimation(self.ReadToPlayAnmationData.id,self.ReadToPlayAnmationData.data)
	end
	self.ReadToPlayAnmationData=nil
end


--播放动画
--参数解释
--name:动画名字
--adjustKey:自适应动画播放速度标签（初始化动画时，会设置标签）
--返回动画的播放时间
function M.PlayAnimation(self,name,adjustKey)

	-- 还没有加载成功，推入初始化完成后，自动播放堆栈
	if not  self.Animations[name] then
		if self.IsLoading then
			self.ReadToPlayAnmationData={
				id=name,
				data=adjustKey,
			}
		end
		return
	end
	self.ReadToPlayAnmationData=nil

	local animationTrack=self.AnimationTrack[name]

	local useTime=0
	if adjustKey then -- 自适应动画播放速度
		if not self.AnimationTrackLenght[name] and animationTrack.Length>0 then
			self.AnimationTrackLenght[name]=animationTrack.Length
		end
		local Length=self.AnimationTrackLenght[name]
		if Length then
			local lastPlayTime=self.AnimationTrackPlayedLastTime[adjustKey]
			if  lastPlayTime then
				local newLength=os.clock()-lastPlayTime
				local speed=Length/newLength
				if speed>1 then
					animationTrack:AdjustSpeed(speed)
				end
				useTime=newLength
			end
		end
		self.AnimationTrackPlayedLastTime[adjustKey]=os.clock()
	end
	
	if useTime==0 then
		useTime=animationTrack.Length
	end

	animationTrack:Play()
	self.CurrentTrack=animationTrack
	return useTime
end

--播放动画，使用一个固定时间，通过缩放动画播放速度实现
function M.PlayAnimationByTime(self,name,time)
	local animationTrack=self.AnimationTrack[name]
	local speed=animationTrack.Length/time
	animationTrack:AdjustSpeed(speed)
	animationTrack:Play()
	return time
end


--是否正在播放某些动画，满足任何一个返回true
function M.IsPlaying(self,nameList)
	local tags={}
	for k,v in pairs(nameList) do
		local t=self.AnimationTrack[v]
		assert(t,"self.AnimationTrack[name]==nil:"..v)
		table.insert(tags,t)
	end
	
	local animator = self.parent:GetHumanoid():FindFirstChildOfClass("Animator")
	assert(animator,"animator==nil")
	local animTracks=animator:GetPlayingAnimationTracks()
	for i,track in ipairs(animTracks) do
		for j,tag in pairs(tags) do
			print("track,tag->:",track,tag)
			if tag==track then
				return true
			end
		end
	end
	return false
end

-- 停止播放所有动画
function M.StopAll(self)
	for k,v in pairs(self.AnimationTrack) do
		v:Stop()
	end
	self.CurrentTrack=nil
end

--停止播放某一个动画
function M.StopAnimation(self,name)
	if not  self.Animations[name] then
		return
	end
	self.AnimationTrack[name]:Stop()
	if self.CurrentTrack==self.AnimationTrack[name] then
		self.CurrentTrack=nil
	end
end

-- 停止播放上一次播放的动画
function M.StopCurrentAnimation(self)
	if self.CurrentTrack then
		self.CurrentTrack:Stop()
		self.CurrentTrack=nil
	end
end

return M